package net.funtip.jdbc.entity;

import java.util.Collections;
import java.util.Map;
import java.util.TreeMap;

public class QueryStatisticImpl implements QueryStatistic {

	/**
	 * 

	CREATE TABLE QUERY_STATISTICS (
	       QS_ID                INTEGER NOT NULL,
	       QS_QUERY             VARCHAR(2000),
	       QS_PERCENTAGE        DECIMAL(6,2),
	       QS_EXECUTION_COUNT   INTEGER,
	       QS_EXECUTION_TIME    CHAR(18),
	       QS_NEXT_COUNT        INTEGER,
	       QS_NEXT_TIME         INTEGER
	)
		 IN USERSPACE1
	;

	CREATE UNIQUE INDEX IDX_QS_QUERY ON QUERY_STATISTICS
	(
	       QS_QUERY                       ASC
	);


	ALTER TABLE QUERY_STATISTICS ADD CONSTRAINT PK_QS PRIMARY KEY (QS_ID);
	
	-- 2012-11-08
	ALTER TABLE QUERY_STATISTICS ADD COLUMN QS_PERCENTAGE100 INTEGER;
	
	-- 2012-12-30
	ALTER TABLE QUERY_STATISTICS ALTER COLUMN QS_EXECUTION_COUNT SET DATA TYPE BIGINT;
	ALTER TABLE QUERY_STATISTICS ALTER COLUMN QS_NEXT_COUNT SET DATA TYPE BIGINT;
	ALTER TABLE QUERY_STATISTICS ALTER COLUMN QS_NEXT_TIME SET DATA TYPE BIGINT;
	
	 */


	protected Long id;
	protected String name;
	protected int executionCount;
	protected long executionTime;
	protected long nextTime;
	protected long nextCount;
	protected int percentage;
	protected Map<ParameterSet, Integer> parameterHistogram;

	public QueryStatisticImpl(String name) {
		this();
		setName(name);
	}

	protected QueryStatisticImpl() {
		parameterHistogram = Collections.synchronizedMap(new TreeMap<ParameterSet,Integer>());
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public int getPercentage() {
		return percentage;
	}

	public void setPercentage(int percentage) {
		this.percentage = percentage;
	}

	public int getExecutionCount() {
		return executionCount;
	}

	public void setExecutionCount(int executionCount) {
		this.executionCount = executionCount;
	}

	public long getExecutionTime() {
		return executionTime;
	}

	public void setExecutionTime(long executionTime) {
		this.executionTime = executionTime;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		if (name != null && name.length() > 2000) {
			this.name = name.substring(0, 2000);
		} else {
			this.name = name;
		}
	}

	public long getNextCount() {
		return nextCount;
	}

	public void setNextCount(long nextCount) {
		this.nextCount = nextCount;
	}

	public long getNextTime() {
		return nextTime;
	}

	public long getTotalTime() {
		return getExecutionTime()+getNextTime();
	}

	public void setNextTime(long nextTime) {
		this.nextTime = nextTime;
	}

	public void addExecution(long time, long resultSetSize) {
		this.executionCount++;
		this.executionTime+=time;
	}

	public void addNext(long time) {
		this.nextCount++;
		this.nextTime+=time;
	}

	public int compareTo(QueryStatistic qs) {
		int compare = (int) (qs.getExecutionTime()+qs.getNextTime()-executionTime-nextTime);
		if (compare == 0) {
			if (this.equals(qs))
				return 0;
			return qs.getName().compareTo(getName());
		} else {
			return compare;
		}
	}

	public void add(QueryStatistic qs) {
		setExecutionCount(getExecutionCount()+qs.getExecutionCount());
		setExecutionTime(getExecutionTime()+qs.getExecutionTime());
		setNextCount(getNextCount()+qs.getNextCount());
		setNextTime(getNextTime()+qs.getNextTime());
	}

	public double getAverageExecutionTimeInSec() {
		return getTotalTime()/(1000.0*getExecutionCount());
	}

	public void addParametersForExecution(ParameterSet params) {
		synchronized (parameterHistogram) {
			Integer count = parameterHistogram.get(params);
			if (count == null) {
				count = 1;
			} else {
				count++;
			}
			parameterHistogram.put(params,count);
		}
	}

	public Map<ParameterSet,Integer> getParameterExecutionHistogram() {
		synchronized (parameterHistogram) {
			Map<ParameterSet,Integer> map = new TreeMap<ParameterSet, Integer>(Collections.reverseOrder());
			for (ParameterSet params: parameterHistogram.keySet()) {
				map.put(params, parameterHistogram.get(params));
			}
			return map;
		}
	}

	@Override
	public String toString() {
		return "QueryStatisticImpl [id=" + id + ", name=" + name
				+ ", executionCount=" + executionCount + ", executionTime="
				+ executionTime + ", nextTime=" + nextTime + ", nextCount="
				+ nextCount + ", percentage=" + percentage + "]";
	}



}
